package com.dailyblue.java.spring.boot.security.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dailyblue.java.spring.boot.security.bean.Powers;
import com.dailyblue.java.spring.boot.security.bean.SecurityUsers;
import com.dailyblue.java.spring.boot.security.bean.Users;
import com.dailyblue.java.spring.boot.security.mapper.PowersMapper;
import com.dailyblue.java.spring.boot.security.mapper.UsersMapper;
import com.dailyblue.java.spring.boot.security.service.UsersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService, UserDetailsService {
    @Resource
    private UsersMapper usersMapper;
    @Resource
    private PowersMapper powersMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("开始业务层验证用户信息,账号是:{}", username);
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        Users user = usersMapper.selectOne(wrapper);
        if (user == null) {
            log.info("账号不存在,抛出异常信息");
            throw new UsernameNotFoundException("账号不存在！");
        }
        Set<Powers> powers = powersMapper.findAllPowerByUserId(user.getId());
        String[] powerArray = new String[powers.size() + 1];
        // 存放权限
        int i = 0;
        for (Powers p : powers) {
            powerArray[i] = p.getUrl();
            i++;
        }
        powerArray[i] = "ROLE_roleA";  // 存放角色 必须以ROLE_开头
        // 模拟一组权限
        List<GrantedAuthority> authorities
                = AuthorityUtils.createAuthorityList(powerArray);
        // 产生一个User对象 账号、密码和权限组
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        /*
        String pass = passwordEncoder.encode(user.getPassword());*/
        //return new User(username, pass, authorities);
        // 存放到redis
        ValueOperations<String, String> value = stringRedisTemplate.opsForValue();
        value.set("power:" + user.getId(), JSONArray.toJSONString(authorities));
        log.info("登陆用户成功，加载权限信息,{}", authorities);
        return new SecurityUsers(user, authorities);
    }
}
